package com.google.code.mochaccino.framework.transaction.provider;
/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import bitronix.tm.Configuration;
import bitronix.tm.TransactionManagerServices;
import com.google.code.mochaccino.framework.transaction.TransactionAspect;
import com.google.code.mochaccino.framework.transaction.TransactionManagerImpl;
import com.google.code.mochaccino.framework.transaction.jsr250.BitronixTransactionManagerWrapper;
import com.google.common.base.Preconditions;
import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.transaction.TransactionManager;

/** Transaction Manager Provider */
public class TransactionManagerProvider implements Provider<TransactionManager> {
	public static final String  BITRONIX_SERVER_ID               = "bitronix-server-id";
	public static final String  BITRONIX_LOG_PART1               = "bitronix-log-part1";
	public static final String  BITRONIX_LOG_PART2               = "bitronix-log-part2";
	public static final String  JNDI_USER_TRX                    = "java:comp/UserTransaction";
	private             String  journal                          = "disk";
	private             String  logPart1Filename                 = "btm1.trx.log";
	private             String  logPart2Filename                 = "btm2.trx.log";
	private             String  serverId                         = ManagementFactory.getRuntimeMXBean().getName() + "_trxManager_btm";
	private             boolean asynchronous2Pc                  = false;
	private             boolean currentNodeOnlyRecovery          = true;
	private             boolean disableJmx                       = false;
	private             boolean forceBatchingEnabled             = true;
	private             boolean forcedWriteEnabled               = true;
	private             boolean skipCorruptedLogs                = true;
	private             boolean warnAboutZeroResourceTransaction = false;
	private             int     defaultTransactionTimeout        = (int) TimeUnit.SECONDS.toSeconds( 30 );
	private             int     gracefulShutdownInterval         = (int) TimeUnit.MINUTES.toSeconds( 1 );
	private             int     maxLogSizeInMb                   = 2;

	/**
	 * Empty Constructor for default.
	 */
	public TransactionManagerProvider() {
	}

	@Inject
	public TransactionManagerProvider( @Named( BITRONIX_SERVER_ID ) String serverId, @Named( BITRONIX_LOG_PART1 ) String logPart1Filename, @Named( BITRONIX_LOG_PART2 ) String logPart2Filename ) {
		this.logPart1Filename = Preconditions.checkNotNull( logPart1Filename );
		this.logPart2Filename = Preconditions.checkNotNull( logPart2Filename );
		this.serverId = Preconditions.checkNotNull( serverId );
	}

	@Override
	public TransactionManager get() {
		/* Configure the Transaction Manager */
		Configuration conf = TransactionManagerServices.getConfiguration();
		conf.setLogPart1Filename( logPart1Filename );
		conf.setLogPart2Filename( logPart2Filename );
		conf.setAsynchronous2Pc( asynchronous2Pc );
		conf.setCurrentNodeOnlyRecovery( currentNodeOnlyRecovery );
		conf.setDefaultTransactionTimeout( defaultTransactionTimeout );
		conf.setForceBatchingEnabled( forceBatchingEnabled );
		conf.setForcedWriteEnabled( forcedWriteEnabled );
		conf.setGracefulShutdownInterval( gracefulShutdownInterval );
		conf.setDisableJmx( disableJmx );
		conf.setWarnAboutZeroResourceTransaction( warnAboutZeroResourceTransaction );
		conf.setMaxLogSizeInMb( maxLogSizeInMb );
		conf.setServerId( serverId );
		conf.setSkipCorruptedLogs( skipCorruptedLogs );
		conf.setJndiUserTransactionName( JNDI_USER_TRX );
		conf.setJournal( journal );

		/* Initialize Transaction Manager */
		BitronixTransactionManagerWrapper bean = new BitronixTransactionManagerWrapper( TransactionManagerServices.getTransactionManager() );

		/* Set the Transaction Manager in aspect */
		TransactionAspect.setTransactionManager( new TransactionManagerImpl( bean ) );

		return bean;
	}

	public void setAsynchronous2Pc( boolean asynchronous2Pc ) {
		this.asynchronous2Pc = asynchronous2Pc;
	}

	public void setCurrentNodeOnlyRecovery( boolean currentNodeOnlyRecovery ) {
		this.currentNodeOnlyRecovery = currentNodeOnlyRecovery;
	}

	public void setDefaultTransactionTimeout( int defaultTransactionTimeout ) {
		this.defaultTransactionTimeout = defaultTransactionTimeout;
	}

	public void setDisableJmx( boolean disableJmx ) {
		this.disableJmx = disableJmx;
	}

	public void setForceBatchingEnabled( boolean forceBatchingEnabled ) {
		this.forceBatchingEnabled = forceBatchingEnabled;
	}

	public void setForcedWriteEnabled( boolean forcedWriteEnabled ) {
		this.forcedWriteEnabled = forcedWriteEnabled;
	}

	public void setGracefulShutdownInterval( int gracefulShutdownInterval ) {
		this.gracefulShutdownInterval = gracefulShutdownInterval;
	}

	public void setJournal( String journal ) {
		this.journal = journal;
	}

	public void setMaxLogSizeInMb( int maxLogSizeInMb ) {
		this.maxLogSizeInMb = maxLogSizeInMb;
	}

	public void setSkipCorruptedLogs( boolean skipCorruptedLogs ) {
		this.skipCorruptedLogs = skipCorruptedLogs;
	}

	public void setWarnAboutZeroResourceTransaction( boolean warnAboutZeroResourceTransaction ) {
		this.warnAboutZeroResourceTransaction = warnAboutZeroResourceTransaction;
	}
}
